package com.gewu.pm.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.LinearInterpolator;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
 * 通用圆环进度控件 - 修复版本
 * 
 * 功能特性：
 * 1. 支持多进度显示（可设置任意数量的进度段）
 * 2. 中心可显示两行自定义文字，文字间隔可调
 * 3. 支持自定义圆环宽度、每段进度的颜色
 * 4. 支持自定义文字大小、颜色、间隔
 * 5. 支持动画效果，1秒平滑过渡
 * 6. 空指针安全，防止崩溃
 * 
 * 使用方法：
 * 
 * 1. XML布局中使用：
 * <com.gewu.pm.widget.RingProgressViewFixed
 *     android:id="@+id/ring_progress"
 *     android:layout_width="110dp"
 *     android:layout_height="110dp" />
 * 
 * 2. 代码中设置多进度：
 * List<ProgressData> progressList = new ArrayList<>();
 * progressList.add(new ProgressData(8, Color.parseColor("#C90000"), "已交"));
 * progressList.add(new ProgressData(4, Color.parseColor("#FF5500"), "未交"));
 * progressList.add(new ProgressData(2, Color.parseColor("#FFAA00"), "延期"));
 * ringProgress.setProgressList(progressList);
 * 
 * 3. 设置中心文字：
 * ringProgress.setText("已交", "67%");
 * ringProgress.setTopText("总计");
 * ringProgress.setBottomText("14人");
 * 
 * 4. 自定义样式：
 * ringProgress.setRingWidth(dp2px(20));        // 设置圆环宽度
 * ringProgress.setTextSpacing(dp2px(16));      // 设置文字间隔
 * 
 * 5. 兼容旧版本双进度：
 * ringProgress.setProgress(submittedCount, unsubmittedCount);
 * 
 * 默认配置：
 * - 圆环宽度：15dp
 * - 文字间隔：20dp（避免重叠）
 * - 第一行文字：16sp，#333333
 * - 第二行文字：14sp，#666666
 * - 背景颜色：#F0F0F0（浅灰）
 * - 已交颜色：#C90000（深红）
 * - 未交颜色：#FF5500（橙红）
 * 
 * 注意事项：
 * - 控件尺寸建议110dp以上，确保文字显示完整
 * - 文字间隔默认20dp，可根据需要调整
 * - 支持任意数量进度段，颜色需在ProgressData中指定
 * - 动画时长1秒，不可修改
 */
public class RingProgressViewFixed extends View {

    // 画笔对象
    private Paint mBackgroundPaint;
    private Paint mProgressPaint;
    private Paint mTextPaint;
    private RectF mRectF;
    
    // 尺寸相关
    private float mRadius = 100f;
    private float mRingWidth = 15f; // 圆环宽度
    
    // 多进度数据
    private List<ProgressData> mProgressDataList = new ArrayList<>();
    private List<Float> mAnimatedProgressList = new ArrayList<>();
    private List<Float> mTargetProgressList = new ArrayList<>();
    private int mTotalCount = 0;
    
    // 文字相关
    private String mTopText = "已交";
    private String mBottomText = "0%";
    private float mTopTextSize = 48f;
    private float mBottomTextSize = 36f;
    private int mTopTextColor = Color.parseColor("#333333");
    private int mBottomTextColor = Color.parseColor("#666666");
    private float mTextSpacing = 12f; // 文字间隔
    
    // 颜色相关
    private int mBackgroundColor = Color.parseColor("#F0F0F0");
    private int mSubmittedColor = Color.parseColor("#C90000");
    private int mUnsubmittedColor = Color.parseColor("#FF5500");
    
    // 动画相关
    private ValueAnimator mAnimator;
    private static final int ANIMATION_DURATION = 1000;
    private static final float START_ANGLE = -90f;

    public RingProgressViewFixed(Context context) {
        super(context);
        init(context);
    }

    public RingProgressViewFixed(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public RingProgressViewFixed(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        // 设置默认值
        mRingWidth = dp2px(context, 15);
        mTopTextSize = sp2px(context, 16);
        mBottomTextSize = sp2px(context, 14);
        mTextSpacing = dp2px(context, 20); // 进一步增加文字间隔到20dp
        
        // 背景画笔
        mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBackgroundPaint.setColor(mBackgroundColor);
        mBackgroundPaint.setStyle(Paint.Style.STROKE);
        mBackgroundPaint.setStrokeWidth(mRingWidth);
        mBackgroundPaint.setStrokeCap(Paint.Cap.ROUND);
        
        // 通用进度画笔
        mProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mProgressPaint.setStyle(Paint.Style.STROKE);
        mProgressPaint.setStrokeWidth(mRingWidth);
        mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
        
        // 文字画笔
        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        
        // 绘制区域
        mRectF = new RectF();
        
        // 初始化默认数据
        initDefaultData();
    }
    
    private void initDefaultData() {
        mProgressDataList.clear();
        mProgressDataList.add(new ProgressData(0, mSubmittedColor, "已交"));
        mProgressDataList.add(new ProgressData(0, mUnsubmittedColor, "未交"));
        updateProgressLists();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        
        int size = Math.min(w, h);
        mRadius = (size - mRingWidth) / 2f;
        
        float centerX = w / 2f;
        float centerY = h / 2f;
        
        mRectF.set(
            centerX - mRadius,
            centerY - mRadius,
            centerX + mRadius,
            centerY + mRadius
        );
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        if (mRectF == null || mBackgroundPaint == null) {
            return;
        }
        
        // 绘制背景圆环
        canvas.drawArc(mRectF, 0, 360, false, mBackgroundPaint);
        
        // 绘制多进度圆环
        drawMultiProgress(canvas);
        
        // 绘制中心文字
        drawCenterText(canvas);
    }
    
    private void drawMultiProgress(Canvas canvas) {
        if (mProgressDataList == null || mAnimatedProgressList == null || mProgressPaint == null) {
            return;
        }
        
        float currentAngle = START_ANGLE;
        
        for (int i = 0; i < mProgressDataList.size() && i < mAnimatedProgressList.size(); i++) {
            float animatedProgress = mAnimatedProgressList.get(i);
            if (animatedProgress > 0) {
                ProgressData progressData = mProgressDataList.get(i);
                if (progressData != null) {
                    float sweepAngle = 360 * animatedProgress;
                    
                    mProgressPaint.setColor(progressData.getColor());
                    canvas.drawArc(mRectF, currentAngle, sweepAngle, false, mProgressPaint);
                    
                    currentAngle += sweepAngle;
                }
            }
        }
    }

    private void drawCenterText(Canvas canvas) {
        if (mTextPaint == null) return;
        
        float centerX = getWidth() / 2f;
        float centerY = getHeight() / 2f;
        
        // 绘制第一行文字（向上偏移）
        mTextPaint.setTextSize(mTopTextSize);
        mTextPaint.setColor(mTopTextColor);
        
        // 第一行文字位置：中心向上偏移间隔的一半
        float topTextY = centerY - mTextSpacing / 2f;
        canvas.drawText(mTopText, centerX, topTextY, mTextPaint);
        
        // 绘制第二行文字（向下偏移）
        mTextPaint.setTextSize(mBottomTextSize);
        mTextPaint.setColor(mBottomTextColor);
        
        // 第二行文字位置：中心向下偏移间隔的一半
        float bottomTextY = centerY + mTextSpacing / 2f;
        canvas.drawText(mBottomText, centerX, bottomTextY, mTextPaint);
    }

    // ==================== 公共API方法 ====================
    
    /**
     * 设置多进度数据列表（推荐使用）
     * 支持任意数量的进度段，每个进度段可以有不同的颜色
     * 
     * @param progressDataList 进度数据列表，包含数量、颜色、标签
     * 
     * 使用示例：
     * List<ProgressData> list = new ArrayList<>();
     * list.add(new ProgressData(8, Color.RED, "已交"));
     * list.add(new ProgressData(4, Color.ORANGE, "未交"));
     * setProgressList(list);
     */
    public void setProgressList(List<ProgressData> progressDataList) {
        if (progressDataList == null) {
            progressDataList = new ArrayList<>();
        }
        
        mProgressDataList.clear();
        mProgressDataList.addAll(progressDataList);
        
        updateProgressLists();
        startAnimation();
    }
    
    /**
     * 设置双进度（兼容旧版本）
     * 只支持已交/未交两种状态，使用默认颜色
     * 
     * @param submittedCount 已交数量
     * @param unsubmittedCount 未交数量
     */
    public void setProgress(int submittedCount, int unsubmittedCount) {
        mProgressDataList.clear();
        mProgressDataList.add(new ProgressData(submittedCount, mSubmittedColor, "已交"));
        mProgressDataList.add(new ProgressData(unsubmittedCount, mUnsubmittedColor, "未交"));
        
        updateProgressLists();
        startAnimation();
    }
    
    /**
     * 设置中心显示的两行文字
     * 
     * @param topText 第一行文字（上方）
     * @param bottomText 第二行文字（下方）
     */
    public void setText(String topText, String bottomText) {
        this.mTopText = topText == null ? "" : topText;
        this.mBottomText = bottomText == null ? "" : bottomText;
        invalidate();
    }
    
    /**
     * 设置第一行文字（上方）
     * 
     * @param topText 第一行文字内容
     */
    public void setTopText(String topText) {
        this.mTopText = topText == null ? "" : topText;
        invalidate();
    }
    
    /**
     * 设置第二行文字（下方）
     * 
     * @param bottomText 第二行文字内容
     */
    public void setBottomText(String bottomText) {
        this.mBottomText = bottomText == null ? "" : bottomText;
        invalidate();
    }
    
    /**
     * 设置圆环宽度
     * 
     * @param ringWidth 圆环宽度（像素值）
     * 建议范围：10dp-30dp，可使用dp2px()转换
     */
    public void setRingWidth(float ringWidth) {
        this.mRingWidth = ringWidth;
        mBackgroundPaint.setStrokeWidth(mRingWidth);
        mProgressPaint.setStrokeWidth(mRingWidth);
        requestLayout();
    }
    
    /**
     * 设置两行文字之间的间隔
     * 
     * @param textSpacing 文字间隔（像素值）
     * 建议范围：10dp-30dp，默认20dp避免重叠
     */
    public void setTextSpacing(float textSpacing) {
        this.mTextSpacing = textSpacing;
        invalidate();
    }

    private void updateProgressLists() {
        if (mProgressDataList == null) {
            mProgressDataList = new ArrayList<>();
        }
        if (mTargetProgressList == null) {
            mTargetProgressList = new ArrayList<>();
        }
        if (mAnimatedProgressList == null) {
            mAnimatedProgressList = new ArrayList<>();
        }
        
        mTotalCount = 0;
        for (ProgressData data : mProgressDataList) {
            mTotalCount += data.getCount();
        }
        
        mTargetProgressList.clear();
        mAnimatedProgressList.clear();
        
        for (ProgressData data : mProgressDataList) {
            float progress = mTotalCount > 0 ? (float) data.getCount() / mTotalCount : 0f;
            mTargetProgressList.add(progress);
            mAnimatedProgressList.add(0f);
        }
    }

    private void startAnimation() {
        if (mAnimator != null && mAnimator.isRunning()) {
            mAnimator.cancel();
        }
        
        mAnimator = ValueAnimator.ofFloat(0f, 1f);
        mAnimator.setDuration(ANIMATION_DURATION);
        mAnimator.setInterpolator(new LinearInterpolator());
        mAnimator.addUpdateListener(animation -> {
            float animatedValue = (float) animation.getAnimatedValue();
            
            for (int i = 0; i < mTargetProgressList.size() && i < mAnimatedProgressList.size(); i++) {
                float targetProgress = mTargetProgressList.get(i);
                mAnimatedProgressList.set(i, targetProgress * animatedValue);
            }
            
            invalidate();
        });
        mAnimator.start();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mAnimator != null && mAnimator.isRunning()) {
            mAnimator.cancel();
        }
    }

    private float dp2px(Context context, float dp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, 
                context.getResources().getDisplayMetrics());
    }

    private float sp2px(Context context, float sp) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, 
                context.getResources().getDisplayMetrics());
    }
}
